Completed
Push — master ( 91efdf...4b34dd )
by Reetesh
34s
created

scriptjob.js ➔ ???   A

Complexity

Conditions 1
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 0 Features 0
Metric Value
c 6
b 0
f 0
nc 2
dl 0
loc 9
rs 9.6666
cc 1
nop 3
1
'use strict'
2
3
let
4
  retry = require('p-retry'),
5
  Log = require('./../../core/log').Log,
6
  Request = require('./../../core/request').Request,
7
  utils = require('./../../core/utils'),
8
  ScriptJobBase = require('./../core/scriptjob').ScriptJob,
9
  Values = require('./values').Values,
10
  log = new Log('Platforms.CrossBrowserTesting.ScriptJob')
11
12
const VARS = {
13
  server: 'http://hub.crossbrowsertesting.com:80/wd/hub',
14
  detailsUrl: 'https://crossbrowsertesting.com/api/v3/selenium?active=true&build={build}&name={name}',
15
  url: 'https://crossbrowsertesting.com/api/v3/selenium/{platformId}',
16
  username: process.env.CROSSBROWSERTESTING_USERNAME,
17
  accessKey: process.env.CROSSBROWSERTESTING_ACCESS_KEY
18
}
19
20
class ScriptJob extends ScriptJobBase {
21
22
  constructor(url, browser, capabilities) {
23
    capabilities = capabilities || { }
24
    utils.buildParams(capabilities)
25
    delete capabilities.project
26
    let vRet = Values.selenium(browser || { }, capabilities)
27
    vRet.capabilities['username'] = VARS.username
28
    vRet.capabilities['password'] = VARS.accessKey
29
    super(VARS.server, url, vRet.browser, vRet.capabilities)
30
  }
31
32
  create() {
33
    const iteration = () => {
34
      return ScriptJobBase.prototype.create.call(this)
35
      .catch(err => {
36
        if(err.message.match(/Socket timed out after/) ||
37
          err.message.match(/A new session could not be created/))
38
        {
39
          throw err
40
        }
41
        throw new retry.AbortError(err.message)
42
      })
43
    }
44
    return retry(iteration, { retries: 5, minTimeout: 1000, factor: 2 })
45
    .then(() => {
46
      return getPlatformId(this)
47
    })
48
  }
49
50
  markStatus(decider) {
51
    return ScriptJobBase.prototype.markStatus.apply(this, [
52
      decider,
53
      VARS.url.replace(/{platformId}/, this.platformId),
54
      'PUT',
55
      markReqOptions
56
    ])
57
  }
58
59
  screenshot() {
60
    if(!this.session) {
61
      throw new Error('Platforms.CrossBrowserTesting.ScriptJob: session not created yet to take screenshot')
62
    }
63
    // driver's screenshot method does not work with CBT and use their
64
    // Selenium screenshot API needs to be used instead
65
    return writeRequest(VARS.url.replace(/{platformId}/, this.platformId) + '/snapshots', 'POST')
66
  }
67
68
  status() {
69
    return ScriptJobBase.prototype.status.apply(this, [
70
      VARS.url.replace(/{platformId}/, this.platformId),
71
      getOptions,
72
      (response) => {
73
        if(!('active' in response) || !('state' in response)) {
74
          return 'stopped'
75
        }
76
        return (!response.active && 'stopped' === response.state ? 'stopped' : 'running')
77
      }
78
    ])
79
  }
80
81
  stop() {
82
    return ScriptJobBase.prototype.stop.call(this)
83
    .then(() => {
84
      return waitUntilStopped(this)
85
    })
86
  }
87
88
  hasScreenshotOption() {
89
    return ('screenshots' in this.options)
90
  }
91
92
}
93
94
function getPlatformId(scriptJob) {
95
  let url = VARS.detailsUrl
96
    .replace(/{name}/, scriptJob.options.name)
97
    .replace(/{build}/, scriptJob.options.build)
98
  return readRequest(url, 'GET')
99
  .then(response => {
100
    scriptJob.platformId = response.selenium[0].selenium_test_id
101
    log.info('platform-id %d for session %s', scriptJob.platformId, scriptJob.session)
102
    return Promise.resolve(true)
103
  })
104
}
105
106
function markReqOptions(status) {
107
  return {
108
    json: true,
109
    resolveWithFullResponse: true,
110
    body: {
111
      action: 'set_score',
112
      score: 'passed' === status ? 'pass' : 'fail'
113
    },
114
    auth: {
115
      user: VARS.username,
116
      pass: VARS.accessKey
117
    }
118
  }
119
}
120
121
function getOptions() {
122
  return {
123
    json: true,
124
    auth: {
125
      user: VARS.username,
126
      pass: VARS.accessKey
127
    }
128
  }
129
}
130
131
function waitUntilStopped(scriptJob) {
132
  const check = () => {
133
    return readRequest(VARS.url.replace(/{platformId}/, scriptJob.platformId), 'GET')
134
    .then(response => {
135
      if(!response.active && 'stopped' === response.state) {
136
        return true
137
      }
138
      throw new Error('not done yet')
139
    })
140
  },
141
  max = 7, minTimeout = 200, factor = 2
142
  return retry(check, {retries: max, minTimeout: minTimeout, factor: factor})
143
}
144
145
function readRequest(url, method) {
146
  let req = new Request()
147
  return req.request(url, method, getOptions())
148
}
149
150
function writeRequest(url, method, data) {
151
  let req = new Request(), options = getOptions()
152
  options.body = data || { }
153
  return req.request(url, method, options)
154
}
155
156
exports.ScriptJob = ScriptJob
157
exports.ScriptJobVars = VARS
158